
#include <stdlib.h>
#include <net.h>
#include <nand.h>
#include "boot_lib.h"
#include <smdkv210single.h>

#define CONFIG_BOOTFILE				"edu-boot.bin" 
#define CONFIG_KERNELFILE			"zImage" 
#define CONFIG_ROOTFSFILE			"rootfs.yaffs" 
#define CONFIG_DRAMADDR			"0x40000000"
#define CONFIG_APPFILE				"app.bin" 
#define CONFIG_BKBOOT			"u-boot.bin" 

#define CONFIG_SD_ROOTFSFILE		"rootfs.ext4" 


/* LCD */
void LCD_turnon(void);
void LCD_setfgcolor(unsigned int color);
void LCD_setleftcolor(unsigned int color);
void LCD_setprogress(int percentage);


//add by edu
#define CONFIG_CMD_UPDATEIMAGE
#ifdef CONFIG_CMD_UPDATEIMAGE
extern ulong		NetBootFileXferSize;
extern void test_yaffs_downloader(unsigned int size);
extern int do_mmcops(int argc, const char *argv[]);
void update_image(int argc,const char *argv[])
{
	int i = 0;
	int ret;
	char cmdbuf[100] = "tftp 0x40000000 ";
	char *argv_erase[5]  = { NULL, "erase",  "0x0", "0x100000", NULL, };
	char *argv_write[6]  = { NULL, "write",  CONFIG_DRAMADDR, "0x0", "0x100000", NULL, };
	char cmdsdread[50] = "mmc read 0x40000000 0x64000 0x400";
	
	if(argc > 1)
	{
		if(0 == strncmp("help",argv[1],4))
			goto update_help;
		else if(0 == strncmp("boot",argv[1],4))
		{			
			if(argv[2])
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_BOOTFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
			argv_erase[2] = "0x0";
			argv_erase[3] = "0x100000";
			do_nand(4, argv_erase);
			argv_write[3] = "0x00";
			argv_write[4] = "0x100000";
			do_nand(5, argv_write);
			//run_command("nand erase 0 0x50000",0);			
			//run_command("nand write 0x21000000 0 0x50000",0);			
		}
		else if(0 == strncmp("ston",argv[1],4))
		{	
			nand_read_init();
			ret = run_command(cmdsdread);		
			if(ret < 0)
				goto update_help;	
			argv_erase[2] = "0x0";
			argv_erase[3] = "0x100000";
			do_nand(4, argv_erase);
			argv_write[3] = "0x00";
			argv_write[4] = "0x100000";
			do_nand(5, argv_write);
		}
		else if(0 == strncmp("app",argv[1],4))
		{			
			if(argv[2])
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_APPFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
		}
#if 1				
		else if(0 == strncmp("kernel",argv[1],6))
		{	
			if(argc == 3)
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_KERNELFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;
			argv_erase[2] = "0x600000";
			argv_erase[3] = "0x500000";
			do_nand(4, argv_erase);
			
			argv_write[3] = "0x600000";
			argv_write[4] = "0x500000";
			do_nand(5, argv_write);			
			//run_command("nand erase 0x600000 0x500000",0);			
			//run_command("nand write 0x21000000 0x600000 0x500000",0);			
		}
		else if(0 == strncmp("yaffs",argv[1],5))
		{			
			if(argc == 3)
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_ROOTFSFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;	
#if 1
			argv_erase[2] = "0xE00000";
			argv_erase[3] = "0x6E00000";
			do_nand(4, argv_erase);
			
			//run_command("nand erase 0xe00000 0x3cac000",0);
			//sprintf(cmdbuf,"nand write.yaffs 0x21000000 0xe00000 0x%x",NetBootFileXferSize);
			//run_command(cmdbuf,0);			
			sprintf(cmdbuf,"0x%x",NetBootFileXferSize);
			printf("\n yaffs size:%s\n",cmdbuf);
			argv_write[1] = "write.yaffs";
			argv_write[3] = "0xE00000";
			argv_write[4] = cmdbuf;
			do_nand(5, argv_write);			
#else
			test_yaffs_downloader(NetBootFileXferSize);
			argv_erase[2] = "0x9c00000";
			argv_erase[3] = "0x36400000";
			do_nand(NULL, 0, 4, argv_erase);
			argv_erase[2] = "0x7c00000";
			argv_erase[3] = "0x2000000";
			do_nand(NULL, 0, 4, argv_erase);
#endif			
		}	
#endif
		else if(0 == strncmp("image",argv[1],5))
		{	//update bootloader
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_BOOTFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
			argv_erase[2] = "0x0";
			argv_erase[3] = "0x100000";
			do_nand(4, argv_erase);
			argv_write[3] = "0x00";
			argv_write[4] = "0x100000";
			do_nand(5, argv_write);

			//update kernel
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_KERNELFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;
			argv_erase[2] = "0x600000";
			argv_erase[3] = "0x500000";
			do_nand(4, argv_erase);
			
			argv_write[3] = "0x600000";
			argv_write[4] = "0x500000";
			do_nand(5, argv_write);

			//update filesystem
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_ROOTFSFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;	
			argv_erase[2] = "0xE00000";
			argv_erase[3] = "0x6E00000";
			do_nand(4, argv_erase);
			
			sprintf(cmdbuf,"0x%x",NetBootFileXferSize);
			argv_write[1] = "write.yaffs";
			argv_write[3] = "0xE00000";
			argv_write[4] = cmdbuf;
			do_nand(5, argv_write);					
		}
		else if(0 == strncmp("test",argv[1],4))
		{
			LCD_turnon();
			LCD_setfgcolor(0x900000);
			LCD_setleftcolor(0x000010);
			LCD_setprogress(100);
			udelay(3000*1000);
		}
		else
			goto update_help;
	
		//printf("\ntftp rootfs len = %#x\n",NetBootFileXferSize);
		return;
		
	}
update_help:
	_puts(
		"\nupdate image system\n"
		"update app     <imagename> Default param app.bin\n"
		"update boot    <imagename> Default param edu-boot.bin\n"
		"update kernel  <imagename> Default param zImage\n"
		"update yaffs    <imagename> Default param rootfs.yaffs\n"
		"update image Default image: edu-boot.bin/zImage/rootfs.yaffs\n"		
		"update ston     <imagename> update from SD the Bootloader\n"
		);
}

void update_sd_image(int argc,const char *argv[])
{
	int i = 0;
	int ret;
	char cmdbuf[100] = "tftp 0x40000000 ";
	char *argv_write[6]  = { NULL, "write",  CONFIG_DRAMADDR, "0x01", "0x400", NULL, };

	if(argc > 1)
	{
		if(0 == strncmp("help",argv[1],4))
			goto update_help;
		else if(0 == strncmp("boot",argv[1],4))
		{			
			if(argv[2])
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_BOOTFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
			argv_write[3] = "0x01";
			argv_write[4] = "0x400";
			do_mmcops(5, argv_write);
		}
		else if(0 == strncmp("app",argv[1],4))
		{			
			if(argv[2])
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_APPFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
		}
		else if(0 == strncmp("kernel",argv[1],6))
		{	
			if(argc == 3)
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_KERNELFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;			
			argv_write[3] = "0x800";
			argv_write[4] = "0x2000";
			do_mmcops(5, argv_write);			
		}
		else if(0 == strncmp("bkboot",argv[1],6))
		{	
			if(argc == 3)
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_BKBOOT);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;			
			argv_write[3] = "0x64000";
			argv_write[4] = "0x400";
			do_mmcops(5, argv_write);			
		}
		else if(0 == strncmp("ext4",argv[1],5))
		{			
			if(argc == 3)
				strcat(cmdbuf,argv[2]);
			else	
				strcat(cmdbuf,CONFIG_SD_ROOTFSFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;	
			
			sprintf(cmdbuf,"0x%x",(NetBootFileXferSize/512));
			printf("\n fs size:%s\n",cmdbuf);
			argv_write[3] = "0x3000";
			argv_write[4] = cmdbuf;
			do_mmcops(5, argv_write);			
		}	
		else if(0 == strncmp("image",argv[1],5))
		{	//update bootloader
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_BOOTFILE);
			ret = run_command(cmdbuf);		
			if(ret < 0)
				goto update_help;	
			argv_write[3] = "0x01";
			argv_write[4] = "0x400";
			do_mmcops(5, argv_write);

			//update kernel
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_KERNELFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;
			
			argv_write[3] = "0x800";
			argv_write[4] = "0x2000";
			do_mmcops(5, argv_write);

			//update filesystem
			strcpy(cmdbuf,"tftp 0x40000000 ");
			strcat(cmdbuf,CONFIG_SD_ROOTFSFILE);
			ret = run_command(cmdbuf);			
			if(ret < 0)
				goto update_help;	

			sprintf(cmdbuf,"0x%x",(NetBootFileXferSize/512));
			printf("\n fs size:%s\n",cmdbuf);
			argv_write[3] = "0x3000";
			argv_write[4] = cmdbuf;
			do_mmcops(5, argv_write);					
		}
		else
			goto update_help;
	
		return;
		
	}
update_help:
	_puts(
		"\nupdate image system\n"
		"updatesd app     <imagename> Default param app.bin\n"
		"updatesd boot    <imagename> Default param edu-boot.bin\n"
		"updatesd kernel  <imagename> Default param zImage\n"
		"updatesd ext4    <imagename> Default param rootfs.ext4\n"
		"updatesd image Default image: edu-boot.bin/zImage/rootfs.ext4\n"		
		"updatesd bkboot  <imagename> Default param u-boot.bin\n"
		);
}

#endif

